﻿ChangeLog：
2008-06-08 00:09 1.1 by 痴漢公賊
2008-04-26 15:52 1.0 by 痴漢公賊

	《游戏的封包、资源和提取器》

一款游戏，它也许有优秀的剧本、艳丽的cg和动听的音乐，哪怕你不喜欢它，但是其中总会有一点儿让你值得心动的地方，于是你就想把对你唯一有价值的东西从它的里面攫取出来，这就是游戏资源提取器这种直接反映和实现人心欲望的工具出现的动机咯。但是在这之前，你应该还做点准备一对你要面对的东西有点了解，至少它可能是一个可爱的精灵，也可能是一个可怕的恶魔。

【名词解释】
·资源元文件
指制作游戏的原始素材，这些原始素材通常都是一些常见格式的文件，比如最常见的图像格式bmp和png，PCM音源的wav以及具有良好压缩比的ogg格式（注意：多数情况下最初的素材应该是PCM音源，而后为了缩小体积而转换为ogg，这里也把这种经过转换的素材格式也称为元文件）。
·资源文件
指开发者将资源元文件转换为私有格式后的文件数据格式。通常在打包时候，由打包器读取的文件就是资源文件。但是也有资源元文件不经任何变换直接打包的情况，这时资源元文件就等于资源文件。
·打包
指的是将资源文件封装在一起、形成一个聚集文件的过程，也叫封包或者封装。典型的打包行为发生在游戏制作完成前夕，经由开发人员将制作好的资源素材按照资源类型分门别类的封装为聚集文件，并最终冠以一个描述性的文件名。当然凡事都有例外，有的游戏的资源文件没有经过打包处理，而是直接将这些资源文件分门别类的组织成一个清晰的目录结构。
·封包
也叫归档或档案，指那些经过打包过程而最终被创建出来的聚集文件（为了不和封包一词的动词含义搞混，下文用“打包”指代“封包”一词的动词含义）。
·资源型封包
或简称资源封包，特指那些不经过打包过程的资源文件。这种情况下资源型封包就是资源文件。

了解了这些概念之后，自然而然会萌生以下这些问题，希望这里的解释能让你更好的理解这些概念。

【为什么要封装资源文件】
在你浏览游戏目录的时候，总能看到一些有特殊扩展名或者体积异常庞大的家伙。第一反应认为这里面有你想要的东西的家伙应该值得褒奖－你的直觉很敏锐。游戏使用的数据，包括脚本、图片、音频、视频、3D模型等等任何对游戏有用的东西，通常都不会以其最原始的方式直接暴露在众目睽睽之下－至少是在你面前，它们不会裸露相向。因为如果这样做的话，开发者会认为游戏的魔力会降低其可玩性，所以开发者们都尽可能的使用一切手段来保护封包内的资源文件不被破解和提取。但事实上说到底对象也只不过是游戏数据而已，开发者们最好不要误会自己是有恋女情节的父亲在保护女儿，只有有能力把所有零散的数据有机的组合在一起共同演绎并淋漓尽致得彰显表现力的人才是真正的开发者，同时这样的游戏是不怕被破解和提取的。实际上开发者们在他们制作的封包格式上是多少体现出了他们具有这一自恋情结的。
另一方面，好的封包文件格式从一开始就不是为了刻意加密和保护资源文件而被设计出来的，它们的设计初衷仅仅是回归了聚集文件的最简单也是最务实的设计理念－仅仅是为了减小资源文件的体积或者是提高访问资源文件的I/O性能。这种简单就是美的想法无论如何都非常最有说服力。如果看到一个封包做了加密，那我只能认为开发者是个胆小鬼或者自恋狂。如果这是一个通用游戏引擎，那么这种加密保护也纯粹是给抱着同样心态的游戏开发者一点心理安慰。但事实上任何加密保护根本微不足道，只要你运行在通用和公开的处理器上，且没有任何硬件保护措施的情况下。

【封包的命名】
理论上来讲，封包的命名是任意的，它甚至可以没有扩展名，名称也可以用极为马虎的数字从0开始计数的方式来命名。因为识别这些名称的是游戏引擎，而不是留着口水想着怎么拆开它们的你。只要游戏引擎能识别，名字怎么样起都可以。基于这个理由，最让人在意的封包扩展名其实就没那么值得在意了。比如我们常见的3大封包扩展名：.dat（data的缩写）、.pak（package的缩写）和.arc（archive的缩写），能成为3大的理由仅仅是因为使用这种扩展名的封包的游戏系统非常多而已，没有更加深刻的意义了。因为其封包具体结构和内容格式由游戏引擎来解析，所以具体结构也由游戏制作方来决定，如果把所有的.dat都认为是具有相同结构的封包文件，那绝对是大错特错，所以如果你问“.dat是什么格式的文件”，这只是个蠢问题而已（所以从你看过这篇文章开始，不要再问类似这样的蠢问题）。事实上，只有相互具备一致的某些内部特征的一类.dat封包才具有相同结构，也就是说使用这一类相互具备一致的具有某些内部特征的封包文件作为其资源容器的游戏，是由同一个游戏引擎或者SDK（游戏开发工具）开发和制作的。我们没法轻易的认为2个游戏的.dat封包文件就是相同结构的封包，也不能认为能提取其中一个游戏.dat封包的提取工具肯定就能提取另外一个游戏的.dat。你只能认为是2个游戏的游戏引擎或者SDK使用的封包的后缀命名都是.dat而已，其他的一切想法必须经过技术分析论证才行。但是这个道理反过来来说就很有意思了，如果一个游戏系统使用了非常罕见的扩展名作为其封包文件的扩展名，那几乎可以肯定的是：所有使用这种扩展名作为封包文件扩展名命名的游戏，都是使用同一个游戏开发工具制作出来的。也就是说能提取这类封包的资源提取器，就有可能能提取使用相同类型封包的游戏。因为考虑到任何一个设计优良的游戏引擎，都会为封包格式的升级留有余地，只支持某一特定版本的资源提取器依然无法提取格式结构升级的封包文件。

【封包的存在形式】
制作封包的过程和具体的封包格式以及打包工具有关，所以举任何一个实例都显得不具公平性，所以这里只给出通用概念上的打包过程，用括号标记的是可以省略的过程：

资源元文件 (-> 资源文件) (-> 封包文件)

可以看出，资源元文件有时候是直接暴露给我们的，但别高兴地太早，几乎没有“好心”的开发商会采用这种方式处理一些关键资源文件，最明显的是cg（基于前面所述的理由），那些被“区别对待”的资源文件，通常是音频数据。
如果资源文件只做了格式变换而没有打包，那么这种资源文件也可以称作封包（因为有格式变换的步骤），只不过没有做多个文件的聚集操作。这种形式相对前一种形式，开发者通常会有条件的接受，出于便于调试和升级的理由，因为要给一个归档做打补丁的升级操作，可能会非常困难；如果游戏还在开发阶段，这种形式也方便随时替换有问题的资源文件。
资源文件被打包为归档是最常见的情况，因为把所有相关的资源文件整合在一个文件内，理论上有很多好处，但通常这些好处都会被上述的出于不自信的心理而采用的加密手段所抵消甚至过偿。有时候过分的进行保护会给文件升级造成非常大的困难，所以除非开发商愿意克服这种困难编写一个相对复杂的打补丁工具，否则多数开发商愿意把第二种存在方式作为升级选项-如果能够在当前游戏目录下的某个特定位置找到要读取的资源文件，那么游戏引擎就不会再访问封包中的该资源文件了。这个做法很聪明，而且也给游戏汉化带来了莫大的便利。

【封包的一些特例】
这些特例包括：没有扩展名的、内藏在其他文件（一般在宿主文件的尾部）中的封包、没有打包的资源型封包和没有明显内部特征的封包。
·没有扩展名实际上只不过是封包文件命名上的特例，人家就是没有扩展名，你管不着人家。
·内藏在其他文件中的封包，通常都附着在游戏主程序exe的后面，采用这种方式存储封包的一般都是体验版游戏。如果你见到一个游戏的exe上几十或几百兆，那一定就属于这种情况。把游戏资源打包成这种方式其实相当不好，它唯一的优点就是文件数量非常集约而已，确实很适合体验版这种发布形式。
·没有打包的资源封包，其实就是仅仅对资源元文件进行了一定的处理和转换（有时候甚至没有做任何处理）而不做打包处理的资源文件。通常来说，开发者喜欢把一类资源文件整合在一个目录里，然后把这个目录内的全部文件打包成一个文件，这就是封包这个词“封”的涵义－一个文件可以解出N个资源文件出来。但是封包的另外一个涵义就是资源格式的变换，所以也可以不把所有资源都封装在一起，而是对每个资源都进行相应的变换处理（加密和压缩），这样得到的就是没有封装的资源封包（虽然用封包这个词可能不太合适了）。
·没有明显内部特征的封包，其实是从内部结构来看待的，对于一般人来说，它可能有扩展名，甚至是一个很特殊的扩展名，也许它的命名也都很清晰明了。但是这种封包，其内部没有明显标识，能解析它的程序，都是基于了一个假设：假设这个封包应该是怎样怎样的结构，假设它应该在这里存储名字，在这里应该存储偏移值......如果实际情况没有满足假设条件，设计的不好的程序很容易出错。

【封包的内部格式】
TODO

【游戏资源提取器】
游戏资源提取器就是模仿游戏引擎来解析各种游戏封包、并从中将资源保存为元文件的程序工具，元文件就是游戏的原始素材或者是编译结果（比如二进制脚本）。游戏资源提取器的编写有很多方法，最常见的是编写者通常使用逆向工程的手段对目标游戏引擎程序进行反汇编分析、I/O活动跟踪、内存dump等手段，分析出游戏封包的具体内容结构，然后通过编程重新实现解析封包的过程。另外就是某些游戏引擎是开放源代码的，所以借用这些源代码也可以编写出相应的资源提取器出来。
